import { Injectable, Injector } from '@angular/core'
import { OperationsService } from './operations-abstract.service'
import { ITradeQueryParams, ITradePagination, ITrade } from '@shared/interfaces/trade'
import { Observable, throwError } from 'rxjs'
import { HttpClient } from '@angular/common/http'
import { COMB_URL } from 'app/utils/contraints'
import {
  ITradeHoldReq,
  ITradeReleaseReq,
  ITradeHoldCheckReq,
  IHoldReleaseDetailObj,
  IChargeBackPagination,
  IChargeBack,
  IChargeBackQueryParams,
  IChargeBackOperateReq,
  ICodeMsgResponse,
  EChargeBackTransCode,
} from '@shared/interfaces/operation'
import { preProcessParams, encodeParams } from '@shared/decorators'
import { map } from 'rxjs/operators'
import { NzNotificationService } from 'ng-zorro-antd'
import { I18NService } from '@core'
import { IGeneralResponse, IReportResponse } from '@shared/interfaces/response'

@Injectable()
export class OperationsAlinterService implements OperationsService {
  constructor(private injector: Injector, private http: HttpClient) {}
  private get notification(): NzNotificationService {
    return this.injector.get(NzNotificationService)
  }

  private get i18n(): I18NService {
    return this.injector.get(I18NService)
  }

  /**************************************************** 暂扣 ****************************************************/
  @preProcessParams()
  @encodeParams()
  getHoldList(params: ITradeQueryParams, str?: string): Observable<ITradePagination> {
    const url = `${COMB_URL}/camel/settle/riskTrans?${str}`
    return this.http.get<ITradePagination>(url)
  }

  getHoldOne(intStoreCode: string, orderNum: string): Observable<IHoldReleaseDetailObj> {
    const url = `${COMB_URL}/camel/settle/riskTrans/${intStoreCode}/${orderNum}`
    return this.http.get<IHoldReleaseDetailObj>(url)
  }

  @preProcessParams()
  @encodeParams()
  checkHold(data: ITradeHoldCheckReq, str?: string): Observable<ITrade> {
    const url = `${COMB_URL}/camel/settle/checkHold?${str}`
    return this.http.get<ITrade>(url)
  }

  hold(data: ITradeHoldReq): Observable<boolean> {
    const url = `${COMB_URL}/camel/settle/hold`
    return this.http.post<boolean>(url, data)
  }

  release(data: ITradeReleaseReq): Observable<ICodeMsgResponse> {
    const url = `${COMB_URL}/camel/settle/release`
    return this.http.post<ICodeMsgResponse>(url, data)
  }

  /******************************** 差错 ****************************/
  @preProcessParams()
  @encodeParams()
  getChargeBackList(params: IChargeBackQueryParams, str?: string): Observable<IChargeBackPagination> {
    const url = `${COMB_URL}/camel/chargeback/wilderror?${str}`
    return this.http.get<IChargeBackPagination>(url)
  }

  getChargeBackOne(disputeNum: string): Observable<IChargeBack> {
    const url = `${COMB_URL}/camel/chargeback/wilderror/${disputeNum}`
    return this.http.get<IChargeBack>(url)
  }

  handleChargeBack(req: IChargeBackOperateReq, transCode: EChargeBackTransCode): Observable<IGeneralResponse> {
    const url = `${COMB_URL}/camel/chargeback/wilderror/manualtrans/${transCode}`
    return this.http
      .post<IGeneralResponse>(url, req, {
        observe: 'response',
      })
      .pipe(
        map(response => {
          const { status } = response
          if (status === 200) {
            this.notification.success(this.i18n.fanyi('GENERAL.NOTIFICATION.UPDATE_SUCCESS'), '')
            return response.body
          }

          if (status === 202) {
            this.notification.success(this.i18n.fanyi('GENERAL.NOTIFICATION.SUBMIT_TO_AUDIT_SUCCESS'), '')
            return response.body
          }
          throwError(response)
        }),
      )
  }

  @preProcessParams()
  @encodeParams()
  getChargeBackReport(params: IChargeBackQueryParams, str: string): Observable<IReportResponse> {
    const url = `${COMB_URL}/camel/chargeback/wilderrorreport?${str}`
    return this.http.get<IReportResponse>(url)
  }
}
